﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Quartz;
using Quartz.Impl;
using System.Threading;
using FlyLib.Entities;
using System.Data.Linq;
using System.Data.SqlClient;

namespace 作业调度
{
    class TaskPlan
    {       
        /// <summary>
        /// 任务计划
        /// </summary>
        public static IScheduler scheduler = null;
        public static IScheduler GetScheduler()
        {
            if (scheduler != null)
            {
                return scheduler;
            }
            else
            {
                ISchedulerFactory schedf = new StdSchedulerFactory();
                IScheduler sched = schedf.GetScheduler();
                return sched;
            }
        }

        /// <summary>
        /// 添加任务计划
        /// </summary>
        /// <returns></returns>
        public static bool AddScheduleJob(TB_TaskPlan m)
        {
            try
            {
                if (m != null)
                {
                    if (m.startTime == null)
                    {
                        m.startTime = DateTime.Now;
                    }
                    DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(m.startTime, 1);
                    if (m.endTime == null)
                    {
                        m.endTime = DateTime.MaxValue.AddDays(-1);
                    }
                    DateTimeOffset endRunTime = DateBuilder.NextGivenSecondDate(m.endTime, 1);
                    scheduler = GetScheduler();
                    IJobDetail job = JobBuilder.Create<HttpJob>()
                      .WithIdentity(m.taskName, m.taskGroup)
                      .Build();
                    ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
                                                 .StartAt(starRunTime)
                                                 .EndAt(endRunTime)
                                                 .WithIdentity(m.taskName, m.taskGroup)
                                                 .WithCronSchedule(m.cron)
                                                 .Build();
                    scheduler.ScheduleJob(job, trigger);
                    scheduler.Start();
                    //TaskPlan.StopScheduleJob("测试任务1", "分组1");
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                //DoApplication.WriteLogFile(ex.Message + "\r\n" + ex.StackTrace);
                return false;
            }
        }

        /// <summary>
        /// 暂停指定任务计划
        /// </summary>
        /// <returns></returns>
        public static bool StopScheduleJob(string taskName,string taskGroup)
        {
            bool result = false;
            try
            {
                scheduler = GetScheduler();
                scheduler.PauseJob(new JobKey(taskName, taskGroup));
                List<TB_TaskPlan> plan = new List<TB_TaskPlan>();
                using (DataContext dc = new DataContext(DBAccess._connectionString))
                {
                    plan = dc.GetTable<TB_TaskPlan>().ToList();
                    var sm = plan.Where(p => p.taskName == taskName).Where(p => p.taskGroup == taskGroup).FirstOrDefault();
                    //AddScheduleJob(sm);
                    sm.taskStatus = 0;
                    dc.SubmitChanges();
                    result = true;
                }
            }
            catch (Exception ex)
            {
                result = false;
            }
            return result;
        }

        /// <summary>
        /// 开启指定的任务计划
        /// </summary>
        /// <returns></returns>
        public static bool RunScheduleJob(string taskName,string taskGroup)
        {
            bool result = false;
            try
            {
                List<TB_TaskPlan> plan = new List<TB_TaskPlan>();
                using (DataContext dc = new DataContext(DBAccess._connectionString))
                {
                    plan = dc.GetTable<TB_TaskPlan>().ToList();
                    var sm = plan.Where(p => p.taskName == taskName).Where(p => p.taskGroup == taskGroup).FirstOrDefault();
                    AddScheduleJob(sm);
                    sm.taskStatus = 1;
                    dc.SubmitChanges();
                }                              
                scheduler = GetScheduler();
                scheduler.ResumeJob(new JobKey(taskName, taskGroup));
                result = true;                
            }
            catch (Exception ex)
            {
                result = false;
            }
            return result;
        }
    }

    public class HttpJob : IJob
    {
        public void Execute(IJobExecutionContext context)
        {
            ThreadPool.QueueUserWorkItem(delegate(Object o)
            {
                try
                {
                    List<TB_TaskPlan> plan = new List<TB_TaskPlan>();
                    using (DataContext dc = new DataContext(DBAccess._connectionString))
                    {
                        plan = dc.GetTable<TB_TaskPlan>().ToList();
                        var sm = plan.Where(p => p.taskName == context.JobDetail.Key.Name).Where(p => p.taskGroup == context.JobDetail.Key.Group).FirstOrDefault();
                        sm.taskStatus=2;//0任务未开启，1任务运行中，2任务已暂停
                        dc.SubmitChanges();

                        string sql = "insert into TB_Log(description,time) values(@descript,@time)";
                        SqlParameter[] ps = { 
                                            new SqlParameter("@descript","执行计划任务:任务名称-"+context.JobDetail.Key.Name+"，任务分组-"+context.JobDetail.Key.Group),
                                            new SqlParameter("@time",DateTime.Now)
                                            };
                        DBAccess.ExecuteNonQuery(sql,ps);
                        
                        Console.WriteLine("计划任务名称:" + context.JobDetail.Key.Name + ";计划任务分组:" + context.JobDetail.Key.Group);
                    }
                    
                }
                catch (Exception e)
                {

                }
            });

        }
    }
}
